package bpd;

import static org.junit.Assert.assertTrue;
import net.sf.robocode.io.Logger;
import robocode.control.events.BattleCompletedEvent;
import robocode.control.events.TurnEndedEvent;
import robocode.control.snapshot.IRobotSnapshot;

/**
 * Illustrates JUnit testing of the Robocode robot PanzerBot. This test simply verifies that this
 * robot is heading due north or due south after hitting a wall most of the time. Note that if the
 * robot hit a wall and was at the exact same y-coordinate as the center of the battlefield, which
 * is very rare, the robot will turn due east or due west and then move to the center of the
 * battlefield, which is also what is supposed to happen.
 * 
 * @author BJ Peter DeLaCruz
 * @version 1.0
 */
public class TestPanzerBotMoveToCenterTurnHeading extends TestPanzerBotMoveToCenter {
  /** True if the robot is heading due north, due south, due east, or due west. */
  boolean correctHeading = false;
  /** Information about the robot's heading. */
  String headingInfo = "";

  /**
   * After each turn, check to see if PanzerBot hit a wall and is heading due north, due south, due
   * east, or due west. If so, set the corresponding flag.
   * 
   * @param event Information about the current state of the battle
   */
  @Override 
  public void onTurnEnded(TurnEndedEvent event) {
    
    int turn = event.getTurnSnapshot().getTurn(); // Get turn number
    IRobotSnapshot robot = event.getTurnSnapshot().getRobots()[1];
    double xPos = robot.getX();
    double yPos = robot.getY();
    
    // Robot is close to the left or right wall.
    if ((xPos > (width - 40)) || xPos < 40) {
      visitedWall = true;
      bumpedInfo = "\n\nBumped into the left or right wall during turn #" + turn;
      checkHeading(robot, turn);
    }
    // Robot is close to the top or bottom wall.
    else if ((yPos > (height - 40)) || yPos < 40) {
      visitedWall = true;
      bumpedInfo = "\n\nBumped into the top or bottom wall during turn #" + turn;
      checkHeading(robot, turn);
    }

  }
  
  /**
   * Asserts that PanzerBot is heading due north, due south, due east, or due west after hitting
   * a wall at least once during the battle.
   * 
   * @param event Details about the completed battle
   */
  @Override
  public void onBattleCompleted(BattleCompletedEvent event) {
    
    assertTrue("Check Wall", visitedWall);
    assertTrue("Check Heading", correctHeading);
    Logger.realOut.print(headingInfo);
    
  }
  
  /**
   * Determines if the robot is heading due north, due south, due east, or due west after hitting
   * a wall.
   * 
   * @param robot Contains information about the robot, e.g. its gun's heading
   * @param turn Current turn number
   */
  public void checkHeading(IRobotSnapshot robot, int turn) {
    
    // Check to see if the robot's heading is 0, 90, 180, 270, or 360 degrees.
    if (robot.getGunHeading() % (Math.PI / 2) == 0.0) {
      correctHeading = true;
      headingInfo = bumpedInfo + "\nAt turn #" + turn + ", the robot's heading is ";
      headingInfo += (robot.getGunHeading() * 180.0 / Math.PI) + " degrees\n\n";
    }
    
  }
  
}
